/**
 * @file jq-validate-methods.js
 * @author betgar (betgar@163.com)
 * @date 10/13/2018
 * @time 09:28:58
 * @description jquery validate methods.
 */
define([
  'common/date/date-formats',
  'common/date/dayjs',
  'jquery-validate',
  'lodash-core'
], function (
  dateFormats,
  dayjs,
  validator,
  lodash
) {
    'use strict';
    /**
     * jquery validation 的 method说明.
     * value - 是控件的值
     * element - 是校验元素
     * param - 是校验规则
     *
     */


    /**
     *
     * 对比date
     * @param {string} value - 是控件的值
     *          ($(element).val()，当使用第三方控件是不一定正确，所以提供normalizer优先使用)
     * @param {HTMLElement} element - 是校验元素
     * @param {{{targetValue: Function | string, format: string}}} param - rule的配置值.
     * @param {string} method - 对比时使用的方法.
     */
    var compareDate = function (value, element, param, method) {
      var format = param.format, targetValue = typeof (param.targetValue) === 'function' ?
        param.targetValue(param, element) : $(param.targetValue).val();
      if (!targetValue || !value) {
        return false;
      }
      return dayjs(dayjs(value).format(format))[method](dayjs(targetValue).format(format));
    };

    /**
     *
     * 对比time，一定在日期时间的基础上对比（Date + Time）
     * @example
     * var time1 = '12:03:12', time2 = '12:04:00';
     * var date = '2018-10-14';
     * var dateTime1 = date + ' ' + time1, dateTime2 = date + ' ' + time2;
     * var isBefore = dayjs(dateTime1).isBefore(dayjs(dateTime2));
     *
     * @param {string} value - 是控件的值
     *          ($(element).val()，当使用第三方控件是不一定正确，所以提供normalizer优先使用)
     * @param {HTMLElement} element - 是校验元素
     * @param {{{targetValue: Function | string, format: string}}} param - rule的配置值.
     * @param {string} method - 对比时使用的方法.
     */
    var compareTime = function (value, element, param, method) {
      var format = param.format, targetValue = typeof (param.targetValue) === 'function' ?
        param.targetValue(param, element) : $(param.targetValue).val();
      var dateString = dayjs().format(dateFormats.DATE);
      var val = dayjs(value).isValid() ? value : dayjs(dateString + ' ' + value);
      // 防止出现''
      if (!targetValue || !value) {
        return false;
      }
      if (typeof (targetValue) === 'string') {
        targetValue = dayjs(targetValue).isValid() ? targetValue : dayjs(dateString + ' ' + targetValue);
      }
      return dayjs(dayjs(val).format(format))[method](dayjs(targetValue).format(format));
    };

    /**
     * 日期的消息formatter
     * @param {*} param - rule的value值
     * @param {HTMLElement} element - 校验的元素
     * @param {Function} message - 消息
     */
    var dateMessageFormatter = function (param, element, message) {
      var $el = $(element), val = $el.val(), rules = $el.rules(), normalizer = rules.normalizer;
      var value = typeof (normalizer) === 'function' ? normalizer.call(element, val) : val;
      return validator.format(message, [value]);
    };

    var beforeDate, beforeDateTime, afterDate, afterDateTime, beforeTime, afterTime;

    function genDateMehtod(ruleValue, method) {
      return function (value, element, param) {
        var newParam = {
          format: param.format ? param.format : ruleValue.format,
          targetValue: param.targetValue
        }
        return compareDate(value, element, newParam, method);
      };
    }
    function genDateTimeMehtod(ruleValue, method) {
      return function (value, element, param) {
        var newParam = {
          format: param.format ? param.format : ruleValue.format,
          targetValue: param.targetValue
        }
        return compareTime(value, element, newParam, method);
      };
    }
    /**
     *
     * @param  {string | Date} value - 校验元素的值
     * @param  {HTMLElement} element - 校验的元素
     * @param  {{targetValue: Function, format: string}} param - 校验配置的规则值， format默认'HH:mm:ss'
     * @returns {boolean} - 返回校验结果.
     */
    beforeDate = genDateMehtod({
      format: dateFormats.DATE
    }, 'isBefore');

    validator.addMethod('beforeDate', beforeDate, function (param, element) {
      return dateMessageFormatter(param, element, '请选择{0}之前的日期');
    });

    afterDate = genDateMehtod({
      format: dateFormats.DATE
    }, 'isAfter');

    validator.addMethod('afterDate', afterDate, function (param, element) {
      return dateMessageFormatter(param, element, '请选择{0}之后的日期');
    });


    beforeDateTime = genDateMehtod({
      format: dateFormats.DATETIME_SECONDS
    }, 'isBefore');

    validator.addMethod('beforeDateTime', beforeDateTime, function (param, element) {
      return dateMessageFormatter(param, element, '请选择{0}之前的日期时间');
    });

    afterDateTime = genDateMehtod({
      format: dateFormats.DATETIME_SECONDS
    }, 'isAfter');
    validator.addMethod('afterDateTime', afterDateTime, function (param, element) {
      return dateMessageFormatter(param, element, '请选择{0}之后的日期时间');
    });

    beforeTime = genDateTimeMehtod({
      format: dateFormats.DATETIME_SECONDS
    }, 'isBefore');
    validator.addMethod('beforeTime', beforeTime, function (param, element) {
      return dateMessageFormatter(param, element, '请选择{0}之前的时间');
    });

    afterTime = genDateTimeMehtod({
      format: dateFormats.DATETIME_SECONDS
    }, 'isAfter');

    validator.addMethod('afterTime', afterTime, function (param, element) {
      return dateMessageFormatter(param, element, '请选择{0}之后的时间');
    });
    return {
      beforeDate: beforeDate,
      afterDate: afterDate,
      beforeDateTime: beforeDateTime,
      afterDateTime: afterDateTime,
      beforeTime: beforeTime,
      afterTime: afterTime
    };
  });
